package com.cn.xiaonuo.slbfinances.slbreward.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cn.xiaonuo.common.entity.BusinessMessage;
import com.cn.xiaonuo.dbs.core.annotation.DataSource;
import com.cn.xiaonuo.slbfinances.slbreward.entity.SlRewardRecord;
import com.cn.xiaonuo.slbfinances.slbreward.entity.SlRewardSetting;
import com.cn.xiaonuo.slbfinances.slbreward.mapper.CmRewardRecordMapper;
import com.cn.xiaonuo.slbfinances.slbreward.mapper.SlRewardRecordMapper;
import com.cn.xiaonuo.slbfinances.slbreward.mapper.SlRewardSettingMapper;
import com.cn.xiaonuo.slbfinances.slbreward.service.ICoverageRewardActivityService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@Service
public class CoverageRewardActivityServiceImpl extends ServiceImpl<CmRewardRecordMapper, String> implements ICoverageRewardActivityService {

    @Autowired
    private CmRewardRecordMapper cmRewardRecordMapper;
    @Autowired
    private SlRewardRecordMapper slRewardRecordMapper;
    @Autowired
    private SlRewardSettingMapper slRewardSettingMapper;
    @Override
    @DataSource(name = "jyb_soole_data_hn")
    public BusinessMessage getRewardList(String phone, String name, Integer start, Integer end, Integer pageNum, Integer pageSize){

        BusinessMessage message = new BusinessMessage();
        if (null == pageNum || pageNum <= 1) {
            pageNum = 1;
        }
        if (null == pageSize || pageSize <= 1) {
            pageSize = 10;
        }
        // 设置分页参数
        PageHelper.startPage(pageNum, pageSize);
        //查询分享商品
        List<Map<String, Object>> list = cmRewardRecordMapper.getRewardList(phone,name,start,end);
        // 执行查询
        PageInfo pageInfo = new PageInfo<>(list);
        if(pageInfo.getList() != null && pageInfo.getList().size() > 0){
            message.setSuccess(true);
            message.setData(pageInfo);
        }else {
            message.setSuccess(false);
            message.setMessage("暂无中奖记录");
        }
        return message;
    }
    @Override
    @DataSource(name = "jyb_soole_data_hn")
    public BusinessMessage generateRewardRecords(String startDate, Integer start, Integer end){
        List<SlRewardRecord> result = new LinkedList<>();
        BusinessMessage message = new BusinessMessage();
        message.setSuccess(false);
        SlRewardRecord sl = new SlRewardRecord();
        sl.setStartTime(start);
        sl.setEndTime(end);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.setEntity(sl);
        Integer rows = this.slRewardRecordMapper.selectCount (queryWrapper);
        if(0 < rows){
            message.setMessage("该时段的中奖记录已生成，不能重复生成!");
            return message;
        }
        //(1)查找时段中奖规则
        SlRewardSetting setting = new SlRewardSetting();
        setting.setStartTime(start);
        setting.setEndTime(end);
        QueryWrapper queryWrappers = new QueryWrapper();
        queryWrappers.setEntity(setting);
        setting = slRewardSettingMapper.selectOne(queryWrappers);

        if(null != setting && 0 < setting.getId()){
            Integer lev1Limit = setting.getUserLimitLevel1();//一等奖用户数
            Integer lev2Limit = setting.getUserLimitLevel2();//二等奖用户数
            Integer lev3Limit = setting.getUserLimitLevel3();//三等奖用户数
            //(2)获取有效订单用户
            List<Map<String, Object>> list = cmRewardRecordMapper.getValidOrderUsers(startDate, start, end);
            if(null != list && 0 < list.size()){
                Integer count = list.size();
                //(3)利用随机函数生成中奖记录
                /*
                 * 订单有效用户数:
                 * 1.<=各等奖用户数时，按照订单默认随机生成中奖用户
                 * 2.>各等奖用户数时, 一、二等奖再随机分配生成，三等奖在剩下的用户中按订单默认随机分配中奖用户
                 *
                 *  */
                if(count > (lev1Limit+lev2Limit+lev3Limit)){
                    //(1)生成一等奖中奖记录(随机生成)
                    this.genLevelRewardRecordRandom(result, list, 1, lev1Limit, start, end);
                    //(2)生成二等奖中奖记录(随机生成)
                    this.genLevelRewardRecordRandom(result, list, 2, lev2Limit, start, end);
                }else{
                    //(1)生成一等奖中奖记录(顺序生成)
                    this.genLevelRewardRecordSeq(result, list, 1, lev1Limit, start, end);
                    //(2)生成二等奖中奖记录(顺序生成)
                    if(count >= lev1Limit){
                        this.genLevelRewardRecordSeq(result, list, 2, lev2Limit, start, end);
                    }
                }
                if(count > lev2Limit){
                    //(3)生成三等奖中奖记录(顺序生成)
                    this.genLevelRewardRecordSeq(result, list, 3, lev3Limit, start, end);
                }

                //(4)批量保存中奖记录
                if(0 < result.size()){
                    cmRewardRecordMapper.insertRewardBatch(result);
                    message.setSuccess(true);
                    message.setMessage("中奖记录生成完成");
                }else{
                    message.setMessage("未生成中奖记录");
                }
            }
        }else{
            message.setMessage("未找到时段中奖规则");
        }
        return message;
    }

    /*生成等级中奖记录*/
    private void genLevelRewardRecordRandom(List<SlRewardRecord> result, List<Map<String, Object>> list, Integer lev, Integer count, Integer start, Integer end){
        Integer i = 0;
        Integer total = list.size();
        while(i<count){
            Integer randNum = this.getRandomNum(total);
            //构建等级中奖记录
            this.buildRewardRecord(result, list, randNum, lev, start, end);
            i++;
        }
    }

    /*顺序生成等级中奖记录*/
    @DataSource(name = "jyb_soole_data_hn")
    private void genLevelRewardRecordSeq(List<SlRewardRecord> result, List<Map<String, Object>> list, Integer lev, Integer count, Integer start, Integer end){
        Integer id = 0;
        Integer currentNum = 0;
        for(Map<String,Object> item : list){
            if(currentNum < count){
                id = (Integer)item.get("id");
                //未中奖
                if(!this.isRecordExists(result, id)){
                    String phone =item.get("phone").toString();
                    SlRewardRecord sr = this.createRewardEntity(id, phone, lev, start, end);
                    result.add(sr);
                    currentNum++;
                }
            }else{
                break;
            }
        }
    }

    /*获取随机数*/
    private Integer getRandomNum(Integer count){
        return new Double(Math.random()*count).intValue();
    }

    /*构建中奖信息(随机)*/
    @DataSource(name = "jyb_soole_data_hn")
    private void buildRewardRecord(List<SlRewardRecord> result, List<Map<String, Object>> list, Integer i,Integer lev, Integer start, Integer end){
        Integer id = (Integer)list.get(i).get("id");
        //(1)检测当前随机抽取用户是否已抽奖
        boolean exists = this.isRecordExists(result, id);
        while (exists){
            i = this.getRandomNum(list.size());
            id = (Integer)list.get(i).get("id");
            exists = this.isRecordExists(result, id);
        }
        //(2)创建中奖记录
        String phone =list.get(i).get("phone").toString();
        SlRewardRecord sr = this.createRewardEntity(id, phone, lev, start, end);
        result.add(sr);
    }

    /*是否实体存在*/
    private boolean isRecordExists(List<SlRewardRecord> result, Integer id){
        for(SlRewardRecord sl : result){
            if(sl.getUserId() == id){
                return true;
            }
        }
        return false;
    }
    /*创建实体*/
    private SlRewardRecord createRewardEntity(Integer id,String phone,Integer lev,Integer start,Integer end){
        SlRewardRecord sr = new SlRewardRecord();
        sr.setUserId(id);
        sr.setPhone(phone);
        sr.setRealName(id.toString());
        sr.setRewardLevel(lev);
        sr.setStartTime(start);
        sr.setEndTime(end);
        sr.setCreatedAt(new Date());
        return sr;
    }
}
